package com.baijiayun.liveuibase.widgets;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.SoundPool;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.baijiayun.livecore.context.LPConstants;
import com.baijiayun.liveuibase.R;
import com.baijiayun.liveuibase.utils.FrameAnimation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;


/**
 * Created by yongjiaming on 2018/10/23
 */
public class AwardView extends FrameLayout {
    private FrameAnimation frameAnimation;
    private AnimatorSet scaleInAnimatorSet, scaleOutAnimatorSet;
    private ObjectAnimator rotationAnimator;
    private ImageView starIv, goldenShineIv, medalIv;
    private TextView awardTextTv;
    private SoundPool soundPool;
    private int soundId;
    private float volumeCurrent = 1;
    private int[] endPointLocation;
    private int[] startPointLocation = new int[2];

    public static final int TYPE_AWARD_USER = 1;
    public static final int TYPE_AWARD_GROUP = 2;
    public static final int TYPE_AWARD_ALL = 3;
    public static final int TYPE_AWARD_CUSTOM = 4;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({TYPE_AWARD_USER,TYPE_AWARD_GROUP,TYPE_AWARD_ALL,TYPE_AWARD_CUSTOM})
    public @interface AwardType{}


    public AwardView(@NonNull Context context) {
        this(context, null);
    }

    public AwardView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AwardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        LayoutInflater.from(context).inflate(R.layout.uibase_layout_award, this);
        starIv = findViewById(R.id.award_start_iv);
        goldenShineIv = findViewById(R.id.golden_light_iv);
        medalIv = findViewById(R.id.award_medal_iv);
        awardTextTv = findViewById(R.id.award_medal_text);
        setWillNotDraw(false);
        setOnClickListener(v -> cancelAnim());
    }

    public void setAwardText(String awardText) {
        awardTextTv.setText(awardText);
    }

    public void setAwardMedal(@AwardType int awardType) {
        setAwardMedal(awardType, null);
    }

    public void setAwardMedal(@AwardType int awardType, String awardModeKey) {
        Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.base_ic_award_user);
        switch (awardType) {
            case TYPE_AWARD_USER:
                drawable = getDrawableByAwardKey(awardModeKey);
                break;
            case TYPE_AWARD_GROUP:
                drawable = ContextCompat.getDrawable(getContext(), R.drawable.base_ic_awrad_group);
                break;
            case TYPE_AWARD_ALL:
                drawable = ContextCompat.getDrawable(getContext(), R.drawable.base_ic_awrad_all);
                break;
            default:
                break;
        }
        medalIv.setImageDrawable(drawable);
    }

    private Drawable getDrawableByAwardKey(String key) {
        Drawable drawable = LPConstants.getAwardTypeDrawable(key, LPConstants.AwardTypeDrawable.Picture);
        if (drawable == null) {
            drawable = ContextCompat.getDrawable(getContext(), R.drawable.base_ic_award_user);
        }
        return drawable;
    }

    public void setEndPointLocation(int[] location) {
        endPointLocation = location;
    }

    private boolean endAnimByMyself = false;

    public void startAnim() {
        if (frameAnimation != null) {
            // 播放中，重新开始
            frameAnimation.restartAnimation();

            rotationAnimator.setCurrentPlayTime(0);
            rotationAnimator.start();

            scaleX.setCurrentPlayTime(0);
            scaleY.setCurrentPlayTime(0);
            scaleInAnimatorSet.start();

            if (scaleOutAnimatorSet != null && scaleOutAnimatorSet.isStarted()) {
                endAnimByMyself = true;
                scaleOutAnimatorSet.cancel();
                scaleOutAnimatorSet.removeAllListeners();
                scaleOutAnimatorSet = null;
            }
            removeCallbacks(animRunnable);
            postDelayed(animRunnable, 3000);
        } else {
            initAnim();
        }
        playAudio();
    }

    ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 0, 1f);
    ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 0, 1f);

    public void initAnim() {
        frameAnimation = new FrameAnimation(starIv, getRes(), 33, true);
        frameAnimation.start();
        rotationAnimator = ObjectAnimator.ofFloat(goldenShineIv, "rotation", 0f, 360f);
        rotationAnimator.setDuration(10000);
        rotationAnimator.setRepeatCount(ValueAnimator.INFINITE);
        rotationAnimator.setRepeatMode(ValueAnimator.REVERSE);
        rotationAnimator.start();

        scaleInAnimatorSet = new AnimatorSet();
        scaleInAnimatorSet.setDuration(500);
        scaleInAnimatorSet.setInterpolator(new DecelerateInterpolator());
        scaleInAnimatorSet.playTogether(scaleX, scaleY);
        scaleInAnimatorSet.start();

        postDelayed(animRunnable, 3000);
    }

    private Runnable animRunnable = ()-> {
        if (startPointLocation[0] == 0) {
            getLocationOnScreen(startPointLocation);
        }
        scaleOutAnimatorSet = new AnimatorSet();
        ObjectAnimator scaleOutX = ObjectAnimator.ofFloat(AwardView.this, "scaleX", 1f, 0f);
        ObjectAnimator scaleOutY = ObjectAnimator.ofFloat(AwardView.this, "scaleY", 1f, 0f);
        scaleOutAnimatorSet.setInterpolator(new DecelerateInterpolator());
        //学员不在台上，则不做位移动画
        if (endPointLocation == null) {
            scaleOutAnimatorSet.play(scaleOutX).with(scaleOutY);
        } else {
            ObjectAnimator translateX = ObjectAnimator.ofFloat(this,
                    "translationX", 0,
                    endPointLocation[0] - startPointLocation[0] - (int) (getMeasuredWidth() / 2));
            ObjectAnimator translateY = ObjectAnimator.ofFloat(this,
                    "translationY", 0,
                    endPointLocation[1] - startPointLocation[1] - (int) (getMeasuredHeight() / 2));
            scaleOutAnimatorSet.setDuration(500);
            scaleOutAnimatorSet.play(scaleOutX).with(scaleOutY).with(translateX).with(translateY);
        }

        scaleOutAnimatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                setX(getLeft());
                setY(getTop());
                if (endAnimByMyself) {
                    endAnimByMyself = false;
                    return;
                }
                if (frameAnimation != null) {
                    frameAnimation.stop();
                    frameAnimation = null;
                }
                if (rotationAnimator != null) {
                    rotationAnimator.cancel();
                    rotationAnimator = null;
                }
                releaseAudio();
                if (scaleInAnimatorSet != null) {
                    scaleInAnimatorSet.cancel();
                    scaleInAnimatorSet.removeAllListeners();
                    scaleInAnimatorSet = null;
                }
                // 避免动画结束时view不隐藏而影响事件的传递
                setVisibility(GONE);
            }
        });
        scaleOutAnimatorSet.start();
    };

    private int[] getRes() {
        TypedArray typedArray = getResources().obtainTypedArray(R.array.award_star);
        int len = typedArray.length();
        int[] resId = new int[len];
        for (int i = 0; i < len; i++) {
            resId[i] = typedArray.getResourceId(i, -1);
        }
        typedArray.recycle();
        return resId;
    }


    private void playAudio() {
        releaseAudio();
        AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
        if (am != null) {
            volumeCurrent = am.getStreamVolume(AudioManager.STREAM_MUSIC);
        }
        soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
        soundId = soundPool.load(getContext(), R.raw.award, 1);
        // soundId for reuse later on
        soundPool.setOnLoadCompleteListener((soundPool, sampleId, status) -> soundPool.play(soundId, volumeCurrent, volumeCurrent, 0, 0, 1));
    }

    private void releaseAudio() {
        if (soundPool != null) {
            if (soundId != 0) {
                soundPool.unload(soundId);
            }
            soundPool.release();
            soundPool = null;
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        removeCallbacks(animRunnable);
        cancelAnim();
    }

    private void cancelAnim(){
        releaseAudio();
        if(scaleOutAnimatorSet != null){
            scaleOutAnimatorSet.cancel();
            scaleOutAnimatorSet.removeAllListeners();
            scaleOutAnimatorSet = null;
        }
        if (frameAnimation != null) {
            frameAnimation.stop();
            frameAnimation = null;
        }
        if(rotationAnimator != null){
            rotationAnimator.cancel();
            rotationAnimator = null;
        }
        if(scaleInAnimatorSet != null){
            scaleInAnimatorSet.cancel();
            scaleInAnimatorSet.removeAllListeners();
            scaleInAnimatorSet = null;
        }
        setVisibility(View.GONE);
    }
}
